﻿using System.Runtime.InteropServices;
using YangpuSign.Application.Service.Face;

namespace 人脸识别测试
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello, World!");
            CompareFaceAction("");
        }
        private readonly static IEnginePoor _enginePoor;
        private static double idMixLevel = 0.6;

        private static bool CompareFaceAction(string face)
        {
            var success = true;
            byte[] arrA;
            byte[] arrB;

            arrA = Convert.FromBase64String(face); 
            try
            {
                arrA = Convert.FromBase64String(face); 
            }
            catch (Exception ex)
            {
                try
                {
                    arrA = DecodeUrlBase64(face);
                }
                catch (Exception e)
                {
                    Console.WriteLine("输入的图片格式不正确");
                }

            }
            IntPtr engine = _enginePoor.GetEngine(_enginePoor.FaceEnginePoor);
            CancellationTokenSource tokenSource = new CancellationTokenSource();
            Tuple<bool, IntPtr, string> faceAResult = new Tuple<bool, IntPtr, string>(false, IntPtr.Zero, null);
            Tuple<bool, IntPtr, string> faceBResult = new Tuple<bool, IntPtr, string>(false, IntPtr.Zero, null);

            //调用引擎池逻辑！
            var task = Task.Run(() =>
            {
                while (engine == IntPtr.Zero)
                {
                    Task.Delay(10);
                    if (tokenSource.Token.IsCancellationRequested)
                    {
                        throw new Exception("等待引擎超时！");
                    }
                    engine = _enginePoor.GetEngine(_enginePoor.FaceEnginePoor);
                }

                using (var ms = new MemoryStream(arrA))
                {
                    faceAResult = Arcsoft_Face_Action.TryExtractSingleFaceFeature(ms, 10, engine);
                    if (!faceAResult.Item1)
                    {
                        success = false;
                        var msg = faceAResult.Item3;
                        return;
                    }
                } 
                //活体检测
                using (var ms = new MemoryStream(arrA))
                {
                    Tuple<bool, string> aliveResult = Arcsoft_Face_Action.IsAliveFace(ms, 10, engine);
                    if (!aliveResult.Item1)
                    {
                        success = false;
                        var msg = aliveResult.Item2;

                        return;
                    }
                }

                float result = 0; 
                int compareStatus = ASFFunctions.ASFFaceFeatureCompare(engine, faceAResult.Item2, faceBResult.Item2, ref result);
                if (compareStatus == 0)
                {

                    if (result >= idMixLevel)
                    {
                        
                        var msg = $"相似度: {result}";
                    }
                    else
                    {
                        success = false;
                        var msg = $"相似度: {result}";
                    }
                }
                else
                {
                    success = false;
                    var msg = $"compareStatus error code = {compareStatus}";
                }

            }, tokenSource.Token);
             

            _enginePoor.PutEngine(_enginePoor.FaceEnginePoor, engine);
            Marshal.FreeHGlobal(faceAResult.Item2);
            Marshal.FreeHGlobal(faceBResult.Item2);
            tokenSource.Dispose();
            GC.Collect();
            return success;
        }
        private static byte[] DecodeUrlBase64(string s)
        {
            s = s.Replace('-', '+').Replace('_', '/').PadRight(4 * ((s.Length + 3) / 4), '=');
            return Convert.FromBase64String(s);
        }
    }

    /// <summary>
    /// 比对入参
    /// </summary>
    public class CompareInput2
    {

        /// <summary>
        /// 照片1
        /// </summary>
        public string Face1 { get; set; }

        /// <summary>
        /// 照片2
        /// </summary>
        public string Face2 { get; set; }
    }

}
